<?php

/**
 * 查询用户订单中心服务
 */

namespace App\Service\OrderService\OrderQueryService;

use App\Service\BaseService;
use App\Service\Code\Normal;
use App\Model\PssModel\OrderSupplier;
use Hyperf\DbConnection\Db;
use App\Service\AppService\ExportExcelHandleService;
use App\Model\PssModel\OrderSupplierGoods;
use App\Model\CommodityModel\CommodityArchives;

class QueryUserOrderService extends BaseService
{
    const page_limit = 50;
    const page_size_limit = 100;
    
    /**
     * 导出用户订单列表功能
     * @param array $binfo
     * @param array $param
     * @return mixed
     */
    public function userOrderExport( array $binfo = [] ,array $param = [] )
    {
        $bid    = $binfo['bid'];
        $page   = (int)($param['page'] ?? 1);
        $limit  = (int)($param['limit'] ?? 20);
        $page   = $page >= self::page_limit ? self::page_limit : $page;
        $limit  = $limit >= self::page_size_limit ? self::page_size_limit : $limit;
        $head = [
            '渠道商订单编号',
            '云仓主订单编号',
            '云仓子订单编号',
            '所含商品',
            '商品类型',
            '商品数量',
            '规格起售数量',
            '国际条码',
            '支付申报单号',
            '商户',
            '商品金额',
            '商品税费',
            '运费',
            '优惠金额',
            '订单金额',
            '实际支付金额',
            '商户结算金额',
            '订单状态',
            '订单创建时间',
            '支付时间',
            '物流公司',
            '物流单号',
            '发货时间',
            '收货人姓名',
            '收货人手机号码',
            '付款人姓名',
            '付款人手机号码',
            '身份证号码',
            '收货地址',
            '省市区',
            '是否售后'
        ];
        $merchantUserName = $binfo['name'];
        $page = 1;
        $data = [];
        while ( true )
        {
            $pageInfo = $this->getWhereParam($bid,$page,self::page_size_limit,$param,true);
            if( empty($pageInfo['data']) ) {
                break;
            }
            
            $orderRows  = $pageInfo['data'];
            $orderMap   = array_column($orderRows,null,'order_id');
            $orderIds   = array_keys($orderMap);
            $orderGoodsRows = OrderSupplierGoods::instance()->getSupplierOrderGoodsByOrderIds($orderIds);
            $orderGoodsRowsGroup = [];
            foreach ($orderGoodsRows as $gp) {
                $orderGoodsRowsGroup[$gp['order_id']][] = $gp;
                unset($gp);
            }
        
            foreach ($orderRows as $orderItem)
            {
                $orderGoodsItems    = $orderGoodsRowsGroup[$orderItem['order_id']];
                $discount_money     = $orderItem['discount_money'];
                $goods_money        = $orderItem['goods_money'];
                $order_money        = $orderItem['order_money'];
                $settlement_money   = $orderItem['settlement_money'];
                $delivery_money     = $orderItem['delivery_money'];
                $real_total_money   = $orderItem['real_total_money'];
                $tax_money          = $orderItem['tax'];
                $goodsTypes = $quantitys = $spec_nums = $barcodes = [];
                foreach ($orderGoodsItems as $item)
                {
                    $goodsTypes[]   = CommodityArchives::instance()->goods_types[$item['goods_type']] ??'未定义';
                    $quantitys[]    = $item['quantity'];
                    $spec_nums[]    = $item['spec_num'];
                    $barcodes[]     = $item['barcode']."\t";
                }
                $data[] = [
                    $orderItem['order_sn']."\t",
                    $orderItem['supplier_psn']."\t",
                    $orderItem['supplier_dsn']."\t",
                    implode("|", array_column($orderGoodsItems,'goods_name')),
                    implode("|", $goodsTypes),
                    implode("|", $quantitys),
                    implode("|", $spec_nums),
                    implode("|", $barcodes),
                    $orderItem['supplier_dsn']."\t",
                    $merchantUserName,
                    number_format(bcsub($goods_money, $tax_money,2),2),
                    number_format($tax_money,2),
                    number_format($delivery_money,2),
                    number_format($discount_money,2),
                    number_format($order_money,2),
                    number_format($real_total_money,2),
                    number_format($settlement_money,2),
                    OrderSupplier::instance()->order_status[$orderItem['order_status']] ??'未定义',
                    date("Y-m-d H:i:s",$orderItem['cd']),
                    $orderItem['pay_time'] ? date("Y-m-d H:i:s",$orderItem['pay_time']) : '',
                    $orderItem['express_name'],
                    $orderItem['express_sn']."\t",
                    $orderItem['express_shipping_time'] ? date("Y-m-d H:i:s",$orderItem['express_shipping_time']) : '',
                    $orderItem['receive_name'],
                    $orderItem['recveive_phone']."\t",
                    $orderItem['buyer_realname'],
                    $orderItem['buyer_phone']."\t",
                    $orderItem['buyer_idcard']."\t",
                    $orderItem['receive_address'],
                    $orderItem['province'].'-'.$orderItem['city'].'-'.$orderItem['district'],
                    $orderItem['after_sale_status'] == 1 ? '是' : '否'
                ];
            }
            $page++;
        }
        
        $file_name = '/YunCangUserCenterFile/user_order_file_export_'.(date('YmdHis'));
        return ExportExcelHandleService::instance()->exportFile($head,$data,$file_name);
    }
    
    /**
     * 查询用户订单列表数据
     * @param array $binfo
     * @param array $param
     * @return mixed
     */
    public function queryUserOrderSupplierLists( array $binfo = [] ,array $param = [] ) 
    {
        $bid    = $binfo['bid'];
        $page   = (int)($param['page'] ?? 1);
        $limit  = (int)($param['limit'] ?? 20);
        $page   = $page >= self::page_limit ? self::page_limit : $page;
        $limit  = $limit >= self::page_size_limit ? self::page_size_limit : $limit;
        $page = $this->getWhereParam($bid,$page,$limit,$param);
        foreach ($page['data'] as & $item)
        {
            $item['orderCreateTime']        = date("Y-m-d H:i:s",$item['cd']);
            $item['afterVerifyStatusName']  = OrderSupplier::instance()->after_verify_status[$item['afterVerifyStatus']] ?? '未定义';
            $item['afterSaleStatusName']    = $item['afterSaleStatus'] == 1 ? '是' : '否';
            $item['orderStatusName']        = OrderSupplier::instance()->order_status[$item['orderStatus']] ?? '未定义';
            unset($item['cd']);
        }
        return Normal::returnCode(Normal::SUC,"获取数据成功",$page);
    }
    
    /**
     * 获取字段
     */
    public function getColumns()
    {
        return [
            Db::raw("CONCAT(os.id,'') as orderId"),
            Db::raw("CONCAT(os.order_sn,'') as mainOrderSn"),
            Db::raw("CONCAT(os.supplier_dsn,'') as childOrderSn"),
            Db::raw("os.receive_name as receiveName"),
            Db::raw("os.recveive_phone as receivePhone"),
            Db::raw("os.real_total_money as actualPay"),
            Db::raw("IFNULL(ost.settlement_money,0.00) as settlementMoney"),
            Db::raw("os.after_verify_status as afterVerifyStatus"),
            Db::raw("os.after_sale_status as afterSaleStatus"),
            Db::raw("os.order_status as orderStatus"),
            Db::raw("os.cd"),
        ];
    }

    /**
     * 获取字段
     */
    public function getExportColumns()
    {
        return [
            Db::raw("CONCAT(os.id,'') as order_id"),
            Db::raw("CONCAT(os.order_sn,'') as order_sn"),
            Db::raw("CONCAT(os.supplier_psn,'') as supplier_psn"),
            Db::raw("CONCAT(os.supplier_dsn,'') as supplier_dsn"),
            Db::raw("os.pay_time"),
            Db::raw("os.express_sn"),
            Db::raw("os.express_name"),
            Db::raw("os.express_shipping_time"),
            Db::raw("os.receive_name"),
            Db::raw("os.recveive_phone"),
            Db::raw("os.buyer_realname"),
            Db::raw("os.buyer_phone"),
            Db::raw("os.buyer_idcard"),
            Db::raw("os.province"),
            Db::raw("os.city"),
            Db::raw("os.district"),
            Db::raw("os.receive_address"),
            Db::raw("os.real_total_money"),
            Db::raw("os.order_money"),
            Db::raw("os.discount_money"),
            Db::raw("os.goods_money"),
            Db::raw("os.deliver_money as delivery_money"),
            Db::raw("os.tax"),
            Db::raw("IFNULL(ost.settlement_money,0.00) as settlement_money"),
            Db::raw("os.after_verify_status"),
            Db::raw("os.after_sale_status"),
            Db::raw("os.order_status"),
            Db::raw("os.cd"),
        ];
    }
    
    /**
     * 构建查询参数
     * @param int $bid
     * @param int $page
     * @param int $limit
     * @param array $body
     * @param bool $isExportColumn
     * @return mixed
     */
    public function getWhereParam(int $bid,int $page,int $limit,array $body = [],bool $isExportColumn = false )
    {
        $table = OrderSupplier::instance()->getTable();
        $query = OrderSupplier::instance()
        ->from($table . " as os")
        ->where("os.bid",$bid);
        
        //售后状态
        if( isset($body['after_verify_status']) && in_array($body['after_verify_status'],['0','1','2']) ) {
            $query->where('os.after_verify_status',$body['after_verify_status']);
        }
        
        //是否申请售后
        if( isset($body['after_sale_status']) && in_array($body['after_sale_status'],['0','1']) ) {
            $query->where('os.after_sale_status',$body['after_sale_status']);
        }
        
        //订单时间
        $order_start_time   = !empty($body['create_start_date']) ? strtotime($body['create_start_date']) : 0 ;
        $order_end_time     = !empty($body['create_end_date']) ? strtotime($body['create_end_date']) + 86399 : 0 ;
        if( !empty($order_start_time) && !empty($order_end_time) ) {
            $query->where("os.cd",">=",$order_start_time)->where("os.cd","<=",$order_end_time);
        } else if( !empty($order_start_time) ) {
            $query->where("os.cd",">=",$order_start_time);
        } else if( !empty($order_end_time) ) {
            $query->where("os.cd","<=",$order_end_time);
        }
        
        //订单状态
        if( isset($body['order_status']) && in_array($body['order_status'],['0','1','2']) ) {
            $query->where("os.order_status","=",$body['order_status']);
        }
        
        //订单关键字搜索
        if( !empty($body['search_keyword']) ) {
            $search_keyword = checkFields($body['search_keyword']);
            $query->where(function($query) use ($search_keyword)
            {
                $query
                ->orWhere('os.order_sn',$search_keyword)
                ->orWhere('os.receive_name',$search_keyword)
                ->orWhere('os.recveive_phone',$search_keyword)
                ->orWhere('os.buyer_phone',$search_keyword)
                ->orWhere('os.buyer_idcard',$search_keyword)
                ->orWhere('os.buyer_realname',$search_keyword)
                ->orWhere('os.express_sn',$search_keyword)
                ->orWhere('os.receive_address','like',"%{$search_keyword}%");
            });
        }
        
        //订单商品搜索
        if( !empty($body['goods_name']) ) {
            $goods_name = checkFields($body['goods_name']);
            $query->join("order_supplier_goods as osg",function($join) use ($goods_name){
                $join
                ->on("os.id","=","osg.order_id")
                ->on("os.bid","=","osg.bid")
                ->where("osg.goods_name",'like',"%{$goods_name}%");
            });
        }
        
        if( $isExportColumn ) {
            $columns = self::getExportColumns();
        } else {
            $columns = self::getColumns();
        }
        
        //关联结算金额字段
        $query->leftJoin("order_settlement as ost",function($join){
            $join
            ->on("os.id","=","ost.order_id")
            ->on("os.bid","=","ost.bid")
            ->where("ost.settlement_type",1);
        });
        
        return $query
        ->orderBy("os.id","desc")
        ->paginate($limit,$columns,'page', $page,true)
        ->toArray();
    }
}